import sys
import threading
import time
import traceback


class ThreadRunner(threading.Thread):
  def __init__(self, func, *args, **kwargs):
    super(ThreadRunner, self).__init__()
    self.func = func
    self.args = args
    self.kwargs = kwargs
    self.success = False
    self.result = None
    self.exception = None

  def run(self):
    try:
      self.result = self.func(*self.args, **self.kwargs)
      self.success = True
    except Exception as e:
      traceback.print_exc()
      self.result = None
      self.exception = e
      self.success = False


def execute_thread_runners(runners, description):
  prev_time = time.time()
  print("Start %s..." % description,)
  sys.stdout.flush()
  for runner in runners:
    runner.start()
  for runner in runners:
    runner.join()
    assert runner.success
  print("Done (%fs) %s..." % (
      time.time() - prev_time,
      description,
  ))


def sleep_seconds(second):
  print("Wait for %f seconds..." % second,)
  sys.stdout.flush()
  time.sleep(second)
  print("Done")
